package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.constant.App;
import cn.huiyunche.base.service.enums.EnabledEnum;
import cn.huiyunche.base.service.enums.UserStatusEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.form.BCompanyUserForm;
import cn.huiyunche.base.service.framework.utils.HYCUtils;
import cn.huiyunche.base.service.interfaces.CompanyService;
import cn.huiyunche.base.service.interfaces.SUserService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.BCompanyUserMapper;
import cn.huiyunche.base.service.mappers.SUserMapper;
import cn.huiyunche.base.service.mappers.ext.SUserViewMapper;
import cn.huiyunche.base.service.model.BCompany;
import cn.huiyunche.base.service.model.BCompanyUser;
import cn.huiyunche.base.service.model.SUser;
import cn.huiyunche.base.service.model.SUserExample;
import cn.huiyunche.base.service.query.BCompanyUserQueryConditions;
import cn.huiyunche.base.service.vo.BCompanyUserVo;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.UserShowVo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by zhicheAdmin on 16/12/12.
 */
@Service
public class SUserServiceImpl implements SUserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SUserServiceImpl.class);

    /**
     * 企业默认密码
     */
    private final String C_COMPANY_USER_DEFAULT_PWD = "123456a"; // "123456a";

    @Autowired
    private SUserMapper sUserMapper;

    @Autowired
    private SUserViewMapper sUserViewMapper;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private BCompanyUserMapper bCompanyUserMapper;

    @Autowired
    private Md5PasswordEncoder passwordEncoder;

    @Autowired
    private UserService userService;

    public int insertSelective(SUser sUser) {
        return sUserMapper.insertSelective(sUser);
    }

    public int deleteByPrimaryKey(Long id) {
        return sUserMapper.deleteByPrimaryKey(id);
    }


    public List<SUser> selectByExample(SUserExample example) {
        return sUserMapper.selectByExample(example);
    }

    public SUser selectByPrimaryKey(Long id) {
        return sUserMapper.selectByPrimaryKey(id);
    }

    public int updateByPrimaryKeySelective(SUser record) {
        return sUserMapper.updateByPrimaryKeySelective(record);
    }

    public boolean validPhoneExist(String phone, Integer userType) {
        SUserExample sUserExample = new SUserExample();
        sUserExample.createCriteria().andPhoneEqualTo(phone).andUserTypeEqualTo(userType);
        List<SUser> list = sUserMapper.selectByExample(sUserExample);
        if (list != null && list.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean isDisabled(Long id, String phone, Integer userType) {
        LOGGER.info("SUserServiceImpl.isDisabled params : {}, {}", phone, userType);
        if (StringUtils.isBlank(phone) && null == id) {
            LOGGER.error("SUserServiceImpl.isDisabled param phone or id must not be null");
            throw new IllegalArgumentException("主键或手机号码不能为空");
        }

        if (null == userType) {
            LOGGER.info("SUserServiceImpl.isDisabled param userType must not be null");
            throw new IllegalArgumentException("用户类型不能为空");
        }

        SUserExample example = new SUserExample();
        SUserExample.Criteria criteria = example.createCriteria();
        criteria.andUserTypeEqualTo(userType).andEnableEqualTo(EnabledEnum.T.getValue());
        if (null != id) {
            criteria.andIdEqualTo(id);
        }
        if (StringUtils.isNotBlank(phone)) {
            criteria.andPhoneEqualTo(phone);
        }

        List<SUser> sUsers = sUserMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(sUsers)) {
            return true;
        }

        return false;
    }

    @Override
    public Map<String, Object> listByCondition(PageVo pageVo, BCompanyUserQueryConditions conditions) throws Exception {
        LOGGER.info("SUserServiceImpl.listByConditions params pageVo: {}, conditions: {}", pageVo, conditions);

        if (null == conditions) {
            LOGGER.error("SUserServiceImpl.listByConditions param conditions must not be null");
        }
        // 获取当前登录用户
        UserShowVo userShowVo = this.userService.getCurrentUser();

        String orderByClause = null;

        Map<String, Object> queryMap = new HashMap<>();

        Map<String, Object> map = new HashMap<String, Object>();

        queryMap.put("userId", userShowVo.getId());

        if(null != pageVo) {
            orderByClause = StringUtils.isNotBlank(pageVo.getOrder())?pageVo.getOrder():" su.id DESC";
        }

        if (null != conditions.getDivisionId()) {
            queryMap.put("divisionId", conditions.getDivisionId());
        }

        if (StringUtils.isNotBlank(conditions.getPhone())) {
            queryMap.put("phone", conditions.getPhone());
        }

        if (StringUtils.isNotBlank(conditions.getRealName())) {
            queryMap.put("name", conditions.getRealName());
        }

        if (null != pageVo) {
            pageVo.setTotalRecord(this.sUserViewMapper.countByCondition(queryMap));
            queryMap.put("limitStart", Integer.valueOf(pageVo.getStartIndex()));
            queryMap.put("limitEnd", Integer.valueOf(pageVo.getPageSize()));
            queryMap.put("orderByClause", orderByClause);
        }

        List<BCompanyUserVo> list = new ArrayList<BCompanyUserVo>();

        try {
            list = this.sUserViewMapper.listByCondition(queryMap);
            map.put("list", list);
        } catch (Exception e) {
            LOGGER.error("SUserServiceImpl.listByConditions error: {}", e);
            throw new IllegalArgumentException("查询数据异常");
        }
        if(null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    public Long saveUser(BCompanyUserForm userForm, BindingResult bindingResult) throws Exception {
        LOGGER.info("SUserServiceImpl.saveUser params userForm: {}", userForm);
        if (null == userForm) {
            LOGGER.error("SUserServiceImpl.saveUser userForm must not be null");
            throw new IllegalArgumentException("用户对象不能为空");
        }
        // 校验表单数据
        validateUserForm(bindingResult);

        // 校验重复数据
        validateRepeat(userForm);

        // 设置默认值
        setDefalutValue(userForm);

        SUser user = new SUser();
        BeanUtils.copyProperties(userForm, user);

        return saveData(user, userForm);
    }

    private Long saveData(SUser user, BCompanyUserForm userForm) {
        // 保存用户信息
        try {
            user.setPwd(this.passwordEncoder.encodePassword(C_COMPANY_USER_DEFAULT_PWD,
                    HYCUtils.getConstantPropertiesLoader().getProperty(App.SECURE_KEY)));
            this.sUserMapper.insertSelective(user);
        } catch (Exception e) {
            LOGGER.error("SUserServiceImpl.saveData error: {}", e);
            throw new IllegalArgumentException("新增用户信息异常");
        }
        // 添加公司用户部门关联信息
        BCompanyUser companyUser = new BCompanyUser();
        BeanUtils.copyProperties(userForm, companyUser);
        companyUser.setUserId(user.getId());

        try {
            this.bCompanyUserMapper.insertSelective(companyUser);
        } catch (Exception e) {
            LOGGER.error("SUserServiceImpl.saveData error: {}", e);
            throw new IllegalArgumentException("新增用户部门关联信息异常");
        }
        return user.getId();
    }

    private void validateUserForm(BindingResult bindingResult) {
        LOGGER.info("SUserServiceImpl.validateUserForm params bindingResult: {}", bindingResult);
        if (null == bindingResult) {
            LOGGER.error("SUserServiceImpl.validateUserForm bindingResult is null");
            throw new IllegalArgumentException("BindingResult is null");
        }
        if (bindingResult.hasErrors()) {
            List<ObjectError> errors = bindingResult.getAllErrors();
            LOGGER.error("SUserServiceImpl.validateUserForm error: {}", errors.get(0).getDefaultMessage());
            throw new IllegalArgumentException(errors.get(0).getDefaultMessage());
        }
    }

    private void setDefalutValue(BCompanyUserForm userForm) {
        userForm.setEnable(EnabledEnum.T.getValue());
        userForm.setUserType(UserTypeEnum.SCOMPANY.getValue());
        userForm.setUserStatus(UserStatusEnum.F.getValue());
        // 设置公司ID
        BCompany company = this.companyService.getBCompanyByCurrentUser();
        if (null != company) {
            userForm.setCompanyCode(company.getCompanyCode());
            userForm.setCompanyId(company.getId());
        }
    }

    private void validateRepeat(BCompanyUserForm userForm) {
        LOGGER.info("SUserServiceImpl.validateRepeat params userForm: {}", userForm);
        // 校验手机号是否重复
        SUserExample example = new SUserExample();
        SUserExample.Criteria criteria = example.createCriteria();
        if (null != userForm.getUserId()) {
            criteria.andIdNotEqualTo(userForm.getUserId());
        }
        criteria.andPhoneEqualTo(userForm.getPhone()).andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
        List<SUser> phoneList = this.sUserMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(phoneList)) {
            LOGGER.error("SUserServiceImpl.validateRepeat Mobile phone number has been in existence ");
            throw new IllegalArgumentException("手机号已存在");
        }
        // 校验登录名是否重复
        SUserExample example1 = new SUserExample();
        SUserExample.Criteria criteria1 = example1.createCriteria();
        if (null != userForm.getUserId()) {
            criteria1.andIdNotEqualTo(userForm.getUserId());
        }
        criteria1.andNameEqualTo(userForm.getName()).andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
        List<SUser> nameList = this.sUserMapper.selectByExample(example1);
        if (CollectionUtils.isNotEmpty(nameList)) {
            LOGGER.error("SUserServiceImpl.validateRepeat name has been in existence ");
            throw new IllegalArgumentException("登录名已存在");
        }
    }

    @Override
    public BCompanyUserVo getById(Long id) throws Exception {
        LOGGER.info("SUserServiceImpl.getById param id: {}", id);
        if (null == id || 0 == id) {
            LOGGER.error("SUserServiceImpl.getById id must not be null");
            throw new IllegalArgumentException("用户主键不能为空");
        }
        BCompanyUserVo companyUser = new BCompanyUserVo();
        try {
            companyUser = this.sUserViewMapper.getById(id);
        } catch (Exception e) {
            LOGGER.error("SUserServiceImpl.getById error: {}", e);
            throw new IllegalArgumentException("查询数据异常");
        }
        return companyUser;
    }

    @Override
    public Integer enableOrDisabled(Long id, String enable) throws Exception {
        LOGGER.info("SUserServiceImpl.enableOrDisabled params id: {}, enable: {}", id, enable);
        if (null == id) {
            LOGGER.error("SUserServiceImpl.enableOrDisabled id must not be null");
            throw new IllegalArgumentException("用户主键不能为空");
        } else if (StringUtils.isBlank(enable)) {
            LOGGER.error("SUserServiceImpl.enableOrDisabled enable must not be null");
            throw new IllegalArgumentException("启用或禁用标识不能为空");
        }
        SUser user = this.sUserMapper.selectByPrimaryKey(id);
        if (null != user) {
            String flg = EnabledEnum.getByValue(enable).getValue();
            if (StringUtils.isBlank(flg)) {
                LOGGER.error("SUserServiceImpl.enableOrDisabled enable illegal");
                throw new IllegalArgumentException("启用或禁用标识不合法");
            }
            user.setEnable(flg);
            return this.sUserMapper.updateByPrimaryKeySelective(user);
        }
        return null;
    }
}
